package com.sf.osms.dep.processor;

import java.io.File;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.sf.osms.dep.biz.ICommonServiceBiz;
import com.sf.osms.dep.domain.Agent;
import com.sf.osms.dep.domain.RouterProblemRecord;
import com.sf.osms.dep.groovy.GroovyInterface;
import com.sf.osms.dep.groovy.GroovyUtils;
import com.sf.osms.dep.processor.downloader.EventDownloader;
import com.sf.osms.dep.processor.exception.ExceptionConstants;
import com.sf.osms.dep.processor.exception.RouterException;
import com.sf.osms.dep.processor.handler.EventHandler;
import com.sf.osms.dep.processor.model.EventModel;
import com.sf.osms.dep.processor.parser.EventParser;
import com.sf.osms.dep.processor.persistor.EventPersistor;
import com.sf.osms.dep.processor.util.CollectionUtil;
import com.sf.osms.dep.processor.util.ExceptionUtils;
import com.sf.osms.dep.processor.util.FileUtil;
import com.sf.osms.dep.processor.util.PropertiesUtil;
import com.sf.osms.dep.processor.util.RouterConstants;
import com.sf.osms.dep.processor.util.SwitchUtils;
import com.sf.osms.dep.processor.util.WebserviceUtil;
import com.sf.osms.dep.webservice.email.EmailSender;
/**
 * 处理每个代理的总体逻辑类
 * @author sfhq1405
 *
 * @param <T>
 * @param <E>
 */
public class EventProcessor<T,E>{
	
	private final static Logger logger = Logger.getLogger(EventProcessor.class);

	private EventDownloader downloader;
	private EventParser<T, E> parser;
	private EventHandler<T, E> handler;
	private EventPersistor<T, E> persistor;
	private ICommonServiceBiz commonService;
	
	public void processAgentEvent(Agent agentInfo){
		//必要配置信息的前置检查
		if(null == agentInfo || StringUtils.isBlank(agentInfo.getUploadPath()) 
		   || StringUtils.isBlank(agentInfo.getBackPath()) ||StringUtils.isBlank(agentInfo.getName())
		   || null == agentInfo.getAgentFileMap() || StringUtils.isBlank(agentInfo.getNetNum())){
			
			logger.error("*******代理：" + agentInfo.getName() + "的必要的配置信息不全！");
			RouterProblemRecord routerProblemRecord = new RouterProblemRecord();
			routerProblemRecord.setAgentName(agentInfo.getName());
			routerProblemRecord.setErrorDesc("代理：" + agentInfo.getName() + "的必要的配置信息不全！");
			try {
				commonService.insertRouterProblem(routerProblemRecord);
			} catch (Exception e) {
				logger.error("*******代理：" + agentInfo.getName() + "插入Routerproblem信息异常！"+ExceptionUtils.getExceptionStackString(e));
			}
			return;
		}
		
		List<File> files = null;
		//下载代理对应的目录下的对应规则的所有的文件
		try {
			files = downloader.downloadFiles(agentInfo);
		} catch (Exception e) {
			logger.error("*******代理：" + agentInfo.getName() + "   :下载"+agentInfo.getUploadPath()+"目录中的文件出现异常！*****"+ExceptionUtils.getExceptionStackString(e));
			handleFileProcessException(e,0,null,agentInfo);
		}
		
		if(CollectionUtil.isEmpty(files)){
			return;
		}
		
		//进行正在上传文件的下载到本地的文件处理(直接丢弃)
		Iterator<File> iterators = files.iterator();
		while(iterators.hasNext()){
			File file = iterators.next();
			long length = file.length();
			if(0 == length){
				file.delete(); //进行本地删除
				iterators.remove();
			}
		}
		//进行groovy 加载
		loadGroovy(agentInfo);
		
		logger.info("******代理：" + agentInfo.getName() + "下载的文件有:\n" +CollectionUtil.listFileToFileNameArray(files));
		
		for (File file : files) {
			EventModel<T, E> eventModel = null;
			try {
			    
				//解析文件为初始数据
				logger.info("******代理：" + agentInfo.getName() + "开始解析文件:" + file.getAbsolutePath());
				eventModel = parser.parse(file, agentInfo);
				
			} catch (RouterException e) {
				logger.error("******代理：" + agentInfo.getName() + "   :解析" + file.getAbsolutePath()+"出现异常！******"+ExceptionUtils.getExceptionStackString(e));
				logger.error(ExceptionUtils.getExceptionStackString(e));
				handleFileProcessException(e,1,file,agentInfo);
				return;
			}
			
			try {
				//处理初始数据为DB记录
				logger.info("******代理：" + agentInfo.getName() + "开始处理文件:" + file.getAbsolutePath());
				eventModel = handler.handle(eventModel, agentInfo);
			} catch (Exception e) {
				logger.error("******代理：" + agentInfo.getName() + "   :处理" + file.getAbsolutePath()+"出现异常！******"+ExceptionUtils.getExceptionStackString(e));
				logger.error(ExceptionUtils.getExceptionStackString(e));
				handleFileProcessException(e,2,file,agentInfo);
				return;
			}
			
			//进行groovy对正确的Router集合进行后置处理
			try {
				if(null != agentInfo.getGif()){
					agentInfo.getGif().hanleCorrectRoutersList(eventModel.getCorrectRouter());
				}
				
			} catch (Exception e) {
				logger.error("groovy脚本后置处理正确Router集合出现异常:" + ExceptionUtils.getExceptionStackString(e));
			}
			
			try {
				//进行DB记录的存放和调用接口
				logger.info("******代理：" + agentInfo.getName() + "开始存放数据:" + file.getAbsolutePath());
				persistor.persist(eventModel, agentInfo);
			} catch (Exception e) {
				logger.error("******代理：" + agentInfo.getName() + "   :持久化" + file.getAbsolutePath()+"出现异常！******"+ExceptionUtils.getExceptionStackString(e));
				logger.error(ExceptionUtils.getExceptionStackString(e));
				handleFileProcessException(e,3,file,agentInfo);
				return;
			}
			//进行成功处理文件的删除
			boolean delete = file.delete();
			if(!delete){
				logger.info("******删除文件失败！文件路径为："+file.getAbsolutePath()+"******");
			}
		}
	}

	private void loadGroovy(Agent agentInfo) {
		if(StringUtils.isBlank(agentInfo.getGroovyFilePath())){
			agentInfo.setGif(null);
			return;
		}else{
			try {
				GroovyInterface invokeGroovy = GroovyUtils.invokeGroovy(agentInfo.getGroovyFilePath());
				agentInfo.setGif(invokeGroovy);
			} catch (Exception e) {
				agentInfo.setGif(null);
				logger.error("******代理：" + agentInfo.getName() + "   :加载" + agentInfo.getGroovyFilePath()+"groovy文件异常！******"+ExceptionUtils.getExceptionStackString(e));
			}
		}
	}

	private void handleFileProcessException(Exception ex, Integer errorCode, File processingFile,Agent agentInfo) {
		
		RouterProblemRecord routerProblemRecord = new RouterProblemRecord();
		routerProblemRecord.setAgentName(agentInfo.getName());
		routerProblemRecord.setErrorDesc(ExceptionUtils.getExceptionStackString(ex));
		if(null != processingFile){
			routerProblemRecord.setFileName(FileUtil.getTreeFileName(processingFile.getName()));
			routerProblemRecord.setLocalFilePath(agentInfo.getBackPath() + "/" + processingFile.getName());
		}
		
		
		//2.把错误信息通过邮件发送
		String content = agentInfo.getName() + "</br>";
		try{
			
			switch (errorCode) {
			case 0:
				content = content + ExceptionConstants.DOWN_LOAD_ERROR_INFO;
				routerProblemRecord.setErrorCode(ExceptionConstants.DOWN_LOAD_ERROR_CODE);
				break;
			case 1:
				content = content + ExceptionConstants.PARSE_FILE_ERROR_INFO;
				routerProblemRecord.setErrorCode(ExceptionConstants.PARSE_FILE_ERROR_CODE);
				break;
			case 2:
				content = content + ExceptionConstants.HANDLE_FILE_ERROR_INFO;
				routerProblemRecord.setErrorCode(ExceptionConstants.HANDLE_FILE_ERROR_CODE);
				break;
			case 3:
				content = content + ExceptionConstants.PERSIST_FILE_ERROR_INFO;
				routerProblemRecord.setErrorCode(ExceptionConstants.PERSIST_FILE_ERROR_CODE);
				break;
			}
			
			//进行邮件发送
			EmailSender es = new EmailSender();
			es.setContent(content + "</br>" + ExceptionUtils.getExceptionStackString(ex));
			String fileName = "";
			if(null != processingFile){
				fileName = processingFile.getName();
			}
			es.setSubject("dep exception(" + agentInfo.getBackPath() + "/" + fileName + ")");
			String defReceive = PropertiesUtil.getProperty("dep.mail.to");
			if(StringUtils.isBlank(defReceive)){
				defReceive = RouterConstants.DEP_MAIL_TO;
			}
			es.setDefReceive(defReceive);
			if(SwitchUtils.getSwithBySystemName(SwitchUtils.EMAIL_SWITCH_NAME)){
				WebserviceUtil.invokeEmail(es);
			}
		}catch(Exception e){
			logger.error("*******发送邮件失败*******" + ExceptionUtils.getExceptionStackString(e));
		}
		
		
		try {
			commonService.insertRouterProblem(routerProblemRecord);
		} catch (Exception e) {
			logger.error("******代理：" + agentInfo.getName() + "入库异常信息出现异常！******"+ExceptionUtils.getExceptionStackString(e));
		}
		//进行错误文件的删除
		if(null != processingFile){
			boolean delete = processingFile.delete();
			if(!delete){
				logger.info("******删除文件失败！文件路径为："+processingFile.getAbsolutePath()+"******");
			}
		}
		
		
	}
	
	
	//setter和getter
	public EventDownloader getDownloader() {
		return downloader;
	}

	public void setDownloader(EventDownloader downloader) {
		this.downloader = downloader;
	}
	

	public EventPersistor<T,E> getPersistor() {
		return persistor;
	}

	public void setPersistor(EventPersistor<T,E> persistor) {
		this.persistor = persistor;
	}

	public EventHandler<T, E> getHandler() {
		return handler;
	}

	public void setHandler(EventHandler<T, E> handler) {
		this.handler = handler;
	}
	
	public EventParser<T, E> getParser() {
		return parser;
	}

	public void setParser(EventParser<T, E> parser) {
		this.parser = parser;
	}
	public ICommonServiceBiz getCommonService() {
		return commonService;
	}

	public void setCommonService(ICommonServiceBiz commonService) {
		this.commonService = commonService;
	}

	public EventProcessor(EventDownloader downloader, EventParser<T, E> parser,
			EventHandler<T, E> handler, EventPersistor<T,E> persistor,ICommonServiceBiz commonService) {
		super();
		this.downloader = downloader;
		this.parser = parser;
		this.handler = handler;
		this.persistor = persistor;
		this.commonService = commonService;
	
	}
}
